# -----检测、校验并输出结果-----
import cv2
from PIL import ImageFont, ImageDraw, Image
import numpy as np

# 准备好识别方法
recognizer = cv2.face.LBPHFaceRecognizer_create()

# 使用之前训练好的模型
recognizer.read('trainner.yml')

# 再次调用人脸分类器
cascade_path = "haarcascade_frontalface_default.xml"
face_cascade = cv2.CascadeClassifier(cascade_path)

# 加载一个字体，用于识别后，在图片上标注出对象的名字
fontpath = "./simsun.ttc"  # <== 这里是宋体路径
font = ImageFont.truetype(fontpath, 32)
idnum = 0
# 设置好与ID号码对应的用户名，如下，如0对应的就是初始

names = ['朱泽玉', 'bxf', 'xly', 'zrb', 'user3']

# 调用摄像头
cam = cv2.VideoCapture(0)
minW = 0.1 * cam.get(3)
minH = 0.1 * cam.get(4)

while True:
    ret, img = cam.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 识别人脸
    faces = face_cascade.detectMultiScale(
        gray,
        scaleFactor=1.2,
        minNeighbors=3,  # minNeighbors表示每一个目标至少要被检测到3次才算是真的目标(因为周围的像素和不同的窗口大小都可以检测到人脸)
        minSize=(int(minW), int(minH))
    )
    # 进行校验
    if len(faces) != 0:
        for (x, y, w, h) in faces:
            cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
            idnum, confidence = recognizer.predict(gray[y:y + h, x:x + w])

            # 计算出一个检验结果
            # confidence越小越容易识别不出，confidence越大容易误识别
            if confidence < 60:
                idum = names[idnum]
                confidence = "{0}%", format(round(100 - confidence))
            else:
                idum = "unknown"
                confidence = "{0}%", format(round(100 - confidence))

            # 输出检验结果以及用户名
            img_pil = Image.fromarray(img)
            draw = ImageDraw.Draw(img_pil)
            draw.text((x + 5, y - 50), str(idum), font=font, fill=(0, 255, 0, 0))
            img = np.array(img_pil)

            # cv2.putText(img, str(idum),, font, 1, (0, 0, 255), 1)
            # cv2.putText(img, str(confidence), (x + 5, y + h - 5), font, 1, (0, 0, 0), 1)

            # 展示结果
            cv2.imshow('camera', img)
    else:
        cv2.imshow('camera', img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放资源
cam.release()
cv2.destroyAllWindows()
